layui.define(['jquery', 'http', 'element', 'util'], function (exports) {

    var layer = layui.layer,
        $ = layui.jquery,
        element = layui.element,
        util = layui.util,
        http = layui.http;

    $.getScript(GLOBAL.path.basePath + "/static/lib/jQuery.print.min.js");

    window.DataVerify = {

        isUndefined: function (data) {
            return typeof (data) == "undefined" || data == "undefined";
        },
        isNull: function (data) {
            return null == data;
        },
        isBlank: function (data) {
            return this.isUndefined(data) || this.isNull(data) || "" == data || data.length == '0';
        },
        isEmpty: function (data) {
            return this.isUndefined(data) || this.isNull(data) || data.length == 0;
        },

        isJSON: function (str) {
            if (typeof str == 'string') {
                try {
                    var obj = JSON.parse(str);
                    if (typeof obj == 'object' && obj) {
                        return true;
                    } else {
                        return false;
                    }

                } catch (e) {
                    //console.info('error：' + str + '!!!' + e);
                    return false;
                }
            }
            console.log('It is not a string!')
        },

        /**
         * 是否已过期
         */
        isExpireTime: function(time, expireTime){
            return new Date().getTime() - time > expireTime;
        }
    }
    /**
     * 校验用户是否有访问权限
     * @type {{hasPrivilege: (function(*): boolean)}}
     */
    window.SessionUtils = {

        UserType: {
            SUPER_ADMIN: 1,//超级管理员
            USER: 2//普通用户
        },

        _Data: {},

        getResouces: function () {//获取用户权限

            var that = this;

            if(!this._Data.ResouceMap){

                if(top.SessionUtils._Data.ResouceMap){

                    that._Data.ResouceMap = top.SessionUtils._Data.ResouceMap;

                }else{
                    var resources = this.getLoginUser().resources;

                    this._Data.ResouceMap = {};

                    for(var i = 0; i < resources.length; i++){
                        this._Data.ResouceMap[resources[i].path] = resources[i]
                    }

                    top.SessionUtils._Data.ResouceMap = this._Data.ResouceMap;
                }
            }

            return this._Data.ResouceMap
        },

        hasPerm: function (code) {//校验用户是否有访问权限

            var ResouceMap = this.getResouces();

            return ResouceMap[code] ? true : false;
        },

        getLoginUser: function () {//获取登录用户

            var that = this;

            if (!this._Data.loginUser) {

                if(top.SessionUtils._Data.loginUser){

                    that._Data.loginUser = top.SessionUtils._Data.loginUser;

                }else{

                    http.get({
                        url: GLOBAL.path.adminApi + '/profile',
                        async: false,
                        backFun: function (result) {
                            that._Data.loginUser = result;
                            top.SessionUtils._Data.loginUser = result;
                        }
                    });
                }
            }

            return this._Data.loginUser
        },

        refreshLoginUser: function () {//获取登录用户

            this._Data = {};
            top.SessionUtils._Data = {};

            return this.getLoginUser();
        },

        setToken: function(token){//保存登录token

            LocalStorageUtils.set(GLOBAL.cacheKeys.ACCESS_TOKEN, token)
        },

        getToken: function () {//保存登录token

            let token = LocalStorageUtils.get(GLOBAL.cacheKeys.ACCESS_TOKEN);

            return token;
        },

        isLogin: function () {//是否登录
            let token = LocalStorageUtils.get(GLOBAL.cacheKeys.ACCESS_TOKEN);
            return !DataVerify.isEmpty(token) && this.getLoginUser() != null ? true : false;
        },

        loginOut: function () {//退出登录

            this._Data = {};


            http.post({
                url: GLOBAL.path.adminApi + '/logout',
                async: false,
                backFun: function (result) {

                    top.SessionUtils._Data = {};
                    LocalStorageUtils.set(GLOBAL.cacheKeys.ACCESS_TOKEN, null);
                }
            });
        },

        isSuperAdmin: function () {//是否是超级管理员

            var loginUser = this.getLoginUser();

            return loginUser && this.UserType.SUPER_ADMIN  == loginUser.type;
        }
    };

    window.Org = {

        _Data: {
            deptMap: {},
            userMap: {},
            positionMap: {}
        },

        /**
         * 获取组织
         * @param deptCode
         */
        getDept: function (id) {

            if(DataVerify.isEmpty(id)) return null;

            var dept = top.Org._Data.deptMap[id];

            if(!dept || DataVerify.isExpireTime(dept._expireTime, GLOBAL.cacheExpireTime.ORG)){

                http.get({
                    url: GLOBAL.path.adminApi + '/org/dept/get/' + id,
                    async: false,
                    backFun: function(result){
                        top.Org._Data.deptMap[id] = result;
                        top.Org._Data.deptMap[id]._expireTime = new Date().getTime() + GLOBAL.cacheExpireTime.ORG;
                    }});
            }

            return top.Org._Data.deptMap[id];
        },

        /**
         * 获取组织名称
         * @param deptCode
         */
        getDeptName: function (id) {

            var dept = this.getDept(id);

            return dept == null ? "" : dept.name;
        },

        /**
         * 选择部门窗口
         * @param options:{
         *     callBack: {
         *         module: '',
         *         cmdName: ''
         *     },
         *     singleFlag:
         * }
         */
        selectDept: function(options){

            options.singleFlag = ("undefined" === typeof options.singleFlag) ? false : options.singleFlag;

            Win.open({
                url: GLOBAL.path.basePath + "/view/lib/selectDept?options=" + escape(JSON.stringify(options)),
                title: "选择组织",
                type: 1,
                offset: 'auto',
                height: '700px',
                width: '800px'
            })
        },

        getUser: function (id) {

            if(DataVerify.isEmpty(id)) return null;

            var user = top.Org._Data.userMap[id];

            if(!user || DataVerify.isExpireTime(user._expireTime, GLOBAL.cacheExpireTime.USER)){

                http.get({
                    url: GLOBAL.path.adminApi + '/org/user/get/' + id,
                    async: false,
                    backFun: function(result){
                        top.Org._Data.userMap[id] = result;
                        top.Org._Data.userMap[id]._expireTime = new Date().getTime() + GLOBAL.cacheExpireTime.USER;
                    }});
            }

            return top.Org._Data.userMap[id];
        },

        /**
         * 获取用户名称
         * @param code
         */
        getUserName: function (id) {

            var user = this.getUser(id);

            return user == null ? "" : user.name;
        },

        /**
         * 选择用户窗口
         * @param options:{
         *     callBack: {
         *         module: '',
         *         cmdName: ''
         *     },
         *     singleFlag
         * }
         */
        selectUser: function(options){

            options.singleFlag = ("undefined" === typeof options.singleFlag) ? false : options.singleFlag;

            Win.open({
                url: GLOBAL.path.basePath + "/view/lib/selectUser?options=" + escape(JSON.stringify(options)),
                title: "选择用户",
                type: 1,
                offset: 'auto',
                height: '700px',
                width: '1300px'
            })
        },

        getPosition: function (id) {

            if(DataVerify.isEmpty(id)) return null;

            var position = top.Org._Data.positionMap[id];

            if(!position || DataVerify.isExpireTime(position._expireTime, GLOBAL.cacheExpireTime.POSITION)){

                http.get({
                    url: GLOBAL.path.adminApi + '/org/position/get/' + id,
                    async: false,
                    backFun: function(result){
                        top.Org._Data.positionMap[id] = result;
                        top.Org._Data.positionMap[id]._expireTime = new Date().getTime() + GLOBAL.cacheExpireTime.POSITION;
                    }});
            }

            return top.Org._Data.positionMap[id];
        },

        /**
         * 获取职位名称
         * @param id
         */
        getPositionName: function (id) {

            var position = this.getPosition(id);

            return position == null ? "" : position.name;
        },
    }

    /**
     * 字典工具
     * @type {{getByType: (function(*): *), _Dict: {}}}
     */
    window.Dict = {

        Type: {
            STATE: "STATE", //数据状态
            STORE_STATE: "STORE_STATE", //铺位状态
            YES_NO: "YES_NO", //是否
            SEX: "SEX", //性别
            RESOURCE_TYPE: "RESOURCE_TYPE", //资源类型
            ORG_TYPE: "ORG_TYPE", //组织类型
            NATION: "NATION", //民族
            DEGREE: "DEGREE", //文化程度字典
            MARRIE_STATE: "MARRIE_STATE", //婚姻状态字典
            EMPLOYEE_TYPE: "EMPLOYEE_TYPE", //员工类型
            EMPLOYEE_POSITION: "EMPLOYEE_POSITION",//职务
            DATA_SCOPE: "DATA_SCOPE",//数据权限
            NOTICE_RECEIVER_TYPE: "NOTICE_RECEIVER_TYPE",//公告接收用户类型
            NOTICE_STATE: "NOTICE_STATE",//公告状态
            NOTICE_TOP_STATE: "NOTICE_TOP_STATE",//公告置顶状态

            OBJ_CODE_CREATE_STATE: "OBJ_CODE_CREATE_STATE",//一物一码生成状态
            OBJ_CODE_DETAIL_STATE: "OBJ_CODE_DETAIL_STATE",//一物一码明细状态
            OBJ_CODE_CONFIG: "OBJ_CODE_CONFIG",//一物一码配置
            OBJ_CODE_TYPE: "OBJ_CODE_TYPE"//一物一码类型
        },

        appendType: function(type) {
            this.Type[type] = type;
        },

        _Data: {
            itemMap: {},
            itemNameMap: {},
            dictMap: {}
        },

        findItemByDictCode: function (dictCode) {

            if (!top.Dict._Data.itemMap[dictCode]) {

                http.post({
                    url: GLOBAL.path.adminApi + '/sys/dictItem/list',
                    data: {
                        dictCode: dictCode
                    },
                    async: false,
                    backFun: function (result) {

                        top.Dict._Data.itemMap[dictCode] = result;
                    }
                });
            }

            return top.Dict._Data.itemMap[dictCode];
        },

        getItemName: function (dictCode, value) {

            if(DataVerify.isEmpty(value)) return "";

            var key = dictCode + "_" + value;

            if (!top.Dict._Data.itemNameMap[key]) {

                var dictItems = top.Dict.findItemByDictCode(dictCode);

                for (var i = 0; i < dictItems.length; i++) {

                    if (dictItems[i].value == value) {

                        top.Dict._Data.itemNameMap[key] = dictItems[i].name;

                        break;
                    }
                }
            }

            return top.Dict._Data.itemNameMap[key];
        },

        getItemValue: function (dictCode, name) {

            var result = null;

            var dictItems = top.Dict.findItemByDictCode(dictCode);

            for (var i = 0; i < dictItems.length; i++) {

                if (dictItems[i].name == name) {

                    result = dictItems[i].value;

                    break;
                }
            }

            return result;
        },

        getDict: function (code) {

            if (!top.Dict._Data.dictMap[code]) {

                http.get({
                    url: GLOBAL.path.adminApi + '/sys/dict/getByCode/' + code,
                    async: false,
                    backFun: function (result) {

                        top.Dict._Data.dictMap[code] = result;
                    }
                });
            }

            return top.Dict._Data.dictMap[code];
        },

        getDictName: function (code) {

            if(DataVerify.isEmpty(code)) return "";

            var dict = top.Dict.getDict(code);

            return dict ? dict.name : null;
        },

        viewItem: function(dictCode, title){

            Win.open({
                url: GLOBAL.path.basePath + '/view/lib/tpl_dict?dictCode=' + dictCode,
                title: title ? title : "字典项",
                type: 1,
                width: '350px'
            });
        }

    }

    /**
     * 身份证工具
     * @type {{getAge: Window.Identity.getAge, getBirthay: Window.Identity.getBirthay, getSex: Window.Identity.getSex}}
     */
    window.Identity = {

        getBirthay: function (str) {

            if (!str || str == null || str == "" || str.length < 18) return "";

            try {

                return str.substring(6, 10) + "-" + str.substring(10, 12) + "-" + str.substring(12, 14);

            } catch (e) {
                console.error(e)
            }

        },

        getAge: function (str) {

            if (!str || str == null || str == "" || str.length < 18) return 0;

            try {

                //获取年龄
                var myDate = new Date();
                var month = myDate.getMonth() + 1;
                var day = myDate.getDate();
                var age = myDate.getFullYear() - str.substring(6, 10) - 1;

                if (str.substring(10, 12) < month || str.substring(10, 12) == month && str.substring(12, 14) <= day) {
                    age++;
                }

                return age;

            } catch (e) {
                console.error(e)
            }
        },

        getSex: function (str) {

            if (!str || str == null || str == "" || str.length < 18) return "";

            try {

                if (parseInt(str.substr(16, 1)) % 2 == 1) {
                    return "男";
                } else {
                    return "女";
                }

            } catch (e) {
                console.error(e)
            }
        }
    };


    /**
     * 弹出窗口工具
     * @type {{closeWin: Window.Win.closeWin, win: {}, open: Window.Win.open}}
     */
    window.Win = {

        _wins: {},

        open: function (options) {

            options = options || {};

            options.isFull = ("undefined" === typeof options.isFull) ? true : options.isFull;
            options.offset = ("undefined" === typeof options.offset) ? 'r' : options.offset;
            options.anim = ("undefined" === typeof options.anim) ? -1 : options.anim;
            options.btnAlign = ("undefined" === typeof options.btnAlign) ? 'c' : options.btnAlign;
            options.buttons = ("undefined" === typeof options.buttons) ? [] : options.buttons;
            options.shade = ("undefined" === typeof options.shade) ? 0.001 : options.shade;
            options.shadeClose = ("undefined" === typeof options.shadeClose) ? true : options.shadeClose;
            options.closeBtn = ("undefined" === typeof options.closeBtn) ? 0 : options.closeBtn;
            options.resize = ("undefined" === typeof options.resize) ? false : options.resize;
            options.move = ("undefined" === typeof options.move) ? false : options.move;
            options.type = ("undefined" === typeof options.type) ? 1 : options.type;
            options.skin = ("undefined" === typeof options.skin) ? "layui-anim layui-anim-rl" : options.skin;

            options.isAppendToken = ("undefined" === typeof options.isAppendToken) ? true : options.isAppendToken;

            options.tools = ("undefined" === typeof options.tools) ? [] : options.tools;


            if (!options.title || options.title === '') {
                options.title = false;
            }

            if (!options.width || options.width === '') {
                options.width = '600px';
            }
            if (!options.height || options.height === '') {
                options.height = '100%';
            }

            if (options.type == "1" && options.url) {

                let separator = "?";
                if (options.url.indexOf("?") > 0) {
                    separator = "&";
                }

                options.content = http.getTpl({url: options.url + separator + 'token=' + SessionUtils.getToken()});

            } else if(options.type == "2"){

                if(options.isAppendToken){
                    let separator = "?";
                    if (options.content.indexOf("?") > 0) {
                        separator = "&";
                    }
                    options.content = options.content + separator + 'token=' + SessionUtils.getToken();
                }
            }

            var params = {
                type: options.type,
                title: options.title,
                offset: options.offset,
                area: [options.width, options.height],
                fixed: false, //不固定
                anim: options.anim,
                content: options.content,
                shadeClose: options.shadeClose,
                closeBtn: options.closeBtn,
                resize: options.resize,
                shade: options.shade,
                move: options.move,
                skin: options.skin,
                success: function(layero, index){

                    if (options.success) {
                        options.success(layero, index);
                    }

                   $(layero).find("button[lay-filter='cancle_btn']").click(function () {
                       top.Win._wins[index] = null;
                       top.layer.close(index);
                   });
                },
                cancel: function(index, layero){//右上角关闭回调

                    top.Win._wins[index] = null;

                    if (options.cancel) {
                        options.cancel(layero, index);
                    }

                    //return false 开启该代码可禁止点击该按钮关闭
                },
                resizing: function(layero){
                    layer.iframeAuto(index);
                }
            };

            var index = top.layer.open(params);

            if(options.enablePrint){
                options.tools.push({
                    title: "打印",
                    icon: "layui-icon-print",
                    event: {
                        name: "PRINT_EVENT",
                        backFun: function () {

                            if(options.type == "2"){
                                var target = top.layui.$("#layui-layer-iframe" + index);
                                var title = target.contents().find("title");

                                target.contents().find(".layui-form-tool").hide();
                                target.contents().find(".operation-btn").hide();

                                if(title && title.length > 0){
                                    title.remove();
                                }

                                target[0].contentWindow.print();

                                target.contents().find(".layui-form-tool").show();
                                target.contents().find(".operation-btn").show();
                            }else{

                                var target = top.layui.$("#layui-layer" + index);

                                target.jqprint();
                            }
                        }
                    }
                })
            }

            if(options.tools.length > 0) {

                var toolBtns = [];
                toolBtns.push("<div style=' display: inline-block;float: right;margin-right: -50px;'>")
                for (var i = 0; i < options.tools.length; i++) {
                    toolBtns.push("<div class='layui-inline' style='width: 50px;text-align: center;' title='" + options.tools[i].title + "' lay-event='" + options.tools[i].event.name + "'><i style='font-size: 20px;' class='layui-icon " + options.tools[i].icon + "'></i></div>");
                }
                toolBtns.push("</div>");

                top.layui.$("#layui-layer" + index).find(".layui-layer-title").append(toolBtns.join(""));

                for (var i = 0; i < options.tools.length; i++) {
                    var backFun = options.tools[i].event.backFun;
                    top.layui.$("div[lay-event='" + options.tools[i].event.name + "']").unbind().click(function () {
                        backFun();
                    });
                }
            }

            //if(isFull) layer.full(index);
            top.Win._wins[index] = index;

            return index;
        },

        closeWin: function (index) {

            if (top.Win._wins[index]) {

                top.layer.close(top.Win._wins[index]);

                top.Win._wins[index] = null;

            }
        },

        closeAll: function () {
            top.layer.closeAll();
        }
    };

    window.DateUtil = {

        Pattern: {
            DATE_TIME: "yyyy-MM-dd HH:mm:ss"
        },

        format: function (date, pattern) {
            return util.toDateString(date, pattern || this.Pattern.DATE_TIME)
        },

        addMonth: function(date, month){

            var d=new Date(date);

            d.setMonth(d.getMonth() + month);

            return d.getTime();
        },

        addDay: function(date, day){

            var d=new Date(date);

            d.setDate(d.getDate() + day);

            return d.getTime();
        },

        monthsBetw: function(start, end) {

            const startFullMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
            const endFullMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
            const startDate = new Date(start);
            const endDate = new Date(end);

            // 开始日期参数
            const startYear = startDate.getFullYear();
            const startMonth = startDate.getMonth();
            const startDay = startDate.getDate();

            // 结束日期参数
            const endYear = endDate.getFullYear();
            const endMonth = endDate.getMonth();
            const endDay = endDate.getDate();

            // 判断开始日期是否为闰年
            if (startYear % 4 === 0 && startYear % 400 !== 0) {
                startFullMonth[1] = 29;
            }

            // 判断结束日期是否为闰年
            if (endYear % 4 === 0 && endYear % 400 !== 0) {
                endFullMonth[1] = 29;
            }

            // 计算月份
            const yearDiff = endYear - startYear;
            const monthDiff = endMonth - startMonth - 1;
            let result = 0;

            // 同年的情况下
            if (yearDiff === 0) {
                // 同月的情况下
                if (monthDiff === -1) {
                    result = (endDay - startDay + 1) / startFullMonth[startMonth];
                }
                // 不同月情况下
                if (monthDiff > -1) {
                    // 开始日是否小于结束日
                    if (startDay <= endDay) {
                        result =
                            monthDiff +
                            (startFullMonth[startMonth] - startDay + 1) / startFullMonth[startMonth] +
                            endDay / endFullMonth[endMonth];
                    } else {
                        result =
                            monthDiff +
                            (startFullMonth[startMonth] - startDay + 1) / startFullMonth[startMonth] +
                            endDay / endFullMonth[endMonth];
                    }
                }
            }
            // 不同年的情况下
            if (yearDiff > 0) {
                result =
                    yearDiff * 12 +
                    monthDiff +
                    (startFullMonth[startMonth] - startDay + 1) / startFullMonth[startMonth] +
                    endDay / endFullMonth[endMonth];
            }
            return Utils.keepOneDecimalFull(result);
        }
    }

    window.QueryParam = {

        get: function (name) {

            var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
            var r = window.location.search.substr(1).match(reg);

            return r != null ? unescape(r[2]) : null;
        }
    }

    /**
     * 附件工具
     */
    window.Appendix = {

        Type: {
            DefaultType: "1",

            ServerType: {
                OPERATION_BTN: {
                    value: 1,
                    name: "操作按钮图标"
                }
            },
            ShareCard: {
                SHARE_IMG: {
                    value: 1,
                    name: "分享图片模板"
                }
            }
        },

        find: function (busId, type) {

            var that = this;

            var res = null;

            http.get({
                url: GLOBAL.path.fileApi + '/file/findByTypeAndBusId?busType=' + (type ? type : Appendix.Type.DefaultType) + "&busId=" + busId,
                async: false,
                backFun: function (result) {

                    for (var i = 0; i < result.length; i++) {
                        result[i].path = that.getPath(result[i].id);
                    }

                    res = result;
                }
            });

            return res;
        },

        getPath: function (id) {
            return GLOBAL.path.fileApi + '/file/download/' + id;
        },

        getInfo: function (id) {

            var res = null;

            http.get({
                url: GLOBAL.path.fileApi + '/file/get/' + id,
                async: false,
                backFun: function (result) {
                    res = result;
                }
            });

            return res;
        },

        imgPreview: function (selector) {

            layer.photos({
                photos: selector
                , anim: 5 //0-6的选择，指定弹出图片动画类型，默认随机（请注意，3.0之前的版本用shift参数）
            });
        },

        pdfPreview: function (id) {

            Win.open({
                content: GLOBAL.path.fileApi + '/file/preView/' + id,
                width: '70%',
                height: '95%',
                type: 2,
                offset: 't',
                anim: 0,
                skin: '-1',
                isOutAnim: false
            })
        },

        getPathByBusIdAndType: function (busId, busType) {
            return GLOBAL.path.fileApi + '/file/downloadByBusIdAndBusType?busId=' + busId + '&busType=' + (busType ? busType : Appendix.Type.DefaultType);
        },

        getUploadUrl: function () {
            return GLOBAL.path.fileApi + '/file/upload';
        },
        getDownLoadUrl: function (id) {
            return GLOBAL.path.fileApi + '/file/download/' + id;
        },
        qrcode: function(options){

            var height = options.height || '200px';
            var width = options.width || '200px';

            var area = 100 + parseInt(width) + 'px';

            if(options.hideDownLoad){

                var index = top.layer.open({
                    type: 1,
                    title: false, //不显示标题栏
                    closeBtn: false,
                    area: area,
                    shade: 0.8,
                    id: 'LAY_layuipro', //设定一个id，防止重复弹出
                    btn: ['返回'],
                    btnAlign: 'c',
                    moveType: 1, //拖拽模式，0或者1
                    content: '<div style="padding: 50px; line-height: 22px; background-color: #393D49; color: #fff; font-weight: 300;text-align: center;"><img style="height: ' + height + ';width: ' + width + ';" src="' + GLOBAL.path.adminApi + options.url + ( options.url.indexOf("?") <= 0 ? '?token=' : '&token=') + SessionUtils.getToken() + '&t=' + new Date().getTime() + '"></img></div>',
                    yes: function (layero) {
                        top.layer.close(index);
                    }
                });

            }else{

                var index = top.layer.open({
                    type: 1,
                    title: false, //不显示标题栏
                    closeBtn: false,
                    area: area,
                    shade: 0.8,
                    id: 'LAY_layuipro', //设定一个id，防止重复弹出
                    btn: ['下载', '取消'],
                    btnAlign: 'c',
                    moveType: 1, //拖拽模式，0或者1
                    content: '<div style="padding: 50px; line-height: 22px; background-color: #393D49; color: #fff; font-weight: 300;text-align: center;"><img style="height: ' + height + ';width: ' + width + ';" src="' + GLOBAL.path.adminApi + options.url + ( options.url.indexOf("?") <= 0 ? '?token=' : '&token=') + SessionUtils.getToken() + '&t=' + new Date().getTime() + '"></img></div>',
                    yes: function (layero) {
                        window.open(GLOBAL.path.adminApi + options.url + ( options.url.indexOf("?") <= 0 ? '?token=' : '&token=') + SessionUtils.getToken() + '&t=' + new Date().getTime(), "_blank")
                    },
                    btn2: function () {
                        top.layer.close(index);

                        if(options.closeBackFun){
                            options.closeBackFun();
                        }
                    }
                });
            }
        },

        /**
         * 图像压缩
         */
        imgCompression: function (obj, maxSize){

            var files = obj.pushFile();
            var filesArry = [];
            for (var key in files) { //将上传的文件转为数组形式
                filesArry.push(files[key])
            }
            var index = filesArry.length - 1;
            var file = filesArry[index]; //获取最后选择的图片,即处理多选情况

            if (navigator.appName == "Microsoft Internet Explorer" && parseInt(navigator.appVersion.split(";")[1]
                .replace(/[ ]/g, "").replace("MSIE", "")) < 9) {
                return obj.upload(index, file)
            }
            Utils.canvasDataURL(file, function (blob) {

                var aafile = new File([blob], file.name, {
                    type: file.type
                })
                var isLt1M;
                if (file.size < aafile.size) {
                    isLt1M = file.size
                } else {
                    isLt1M = aafile.size
                }

                if (isLt1M / 1024 / 1024 > maxSize) {
                    return layer.alert('图片压缩之后还是大于" + maxSize + "M，请压缩之后上传！');
                } else {
                    if (file.size < aafile.size) {
                        return obj.upload(index, file)
                    }
                    obj.upload(index, aafile)
                }
            })
        }
    }

    window.FileType = {

        isImg: function (fileName) {

            //获取最后一个.的位置
            var index = fileName.lastIndexOf(".");
            //获取后缀
            var ext = fileName.substr(index + 1);

            return $.inArray(ext, ['png', 'jpg', 'jpeg', 'bmp', 'gif', 'webp', 'psd', 'svg', 'tiff']) >= 0;
        },

        isVideo: function (fileName) {

            //获取最后一个.的位置
            var index = fileName.lastIndexOf(".");
            //获取后缀
            var ext = fileName.substr(index + 1);

            return $.inArray(ext, ["avi","wmv","mpg","mpeg","mov","rm","ram","swf","flv","mp4","mp3","wma","avi","rm","rmvb","flv","mpg","mkv"]) >= 0;
        },

        getFileNameExcludeExt: function (fileName) {

            //获取最后一个.的位置
            var index = fileName.lastIndexOf(".");
            //获取后缀
            var name = fileName.substr(0, index);

            return name && name.length > 10 ? name.substring(0, 10) + '..' : name;
        }
    }

    window.LocalStorageUtils = {

        TABLE: {
            ND_FASTDP: 'ND_FASTDP'
        },

        get: function (tableName, type) {

            return layui.data(tableName)[type];
        },

        get: function (type) {

            return layui.data(LocalStorageUtils.TABLE.ND_FASTDP)[type];
        },

        set: function (tableName, type, value) {

            layui.data(tableName, {
                key: type
                , value: value
            });
        },

        set: function (type, value) {

            layui.data(LocalStorageUtils.TABLE.ND_FASTDP, {
                key: type
                , value: value
            });
        },

        remove: function(type){

            return layui.data(LocalStorageUtils.TABLE.ND_FASTDP,{
                key: type,
                remove: true
            });
        }
    }

    /**
     * 汉语拼音装转工具类
     */
    window.HanyuPinyinHelper = {

        toPinyin: function (text) {

            var res = null;

            http.post({
                url: GLOBAL.path.adminApi + '/public/pinyin',
                async: false,
                data: {
                    text: text
                },
                hideLoading: true,
                backFun: function (result) {
                    res = result;
                }
            });

            return res;
        },

        getFirstLetters: function (text) {

            var res = null;

            http.post({
                url: GLOBAL.path.adminApi + '/public/getFirstLetters',
                async: false,
                data: {
                    text: text
                },
                hideLoading: true,
                backFun: function (result) {
                    res = result;
                }
            });

            return res;
        }
    }
    //判断类型,是否为null empty,undefined
    window.Utils = {
        /**
         * 访问记录
         *
         * {
         *      "module": "测试模块",
         *      "source": "1"
         * }
         *
         */
        visitRecoder: function(options){

            http.post({
                url: GLOBAL.path.adminApi + '/public/visit',
                async: true,
                data: options,
                hideLoading: true
            });
        },
        tips: function (text){
            return "<span title='" + text + "'>" + text + "</span>";
        },
        parseOptions: function(options){

            if(DataVerify.isJSON(options)){
                return JSON.parse(options);
            }

            var result = {};

            var s = $.trim(options);
            if (s){
                if (s.substring(0, 1) != '{'){
                    s = '{' + s + '}';
                }
                result = (new Function('return ' + s))();
            }

            return result;
        },

        digitUppercase: function(n) {

            var fraction = ['角', '分'];
            var digit = [
                '零', '壹', '贰', '叁', '肆',
                '伍', '陆', '柒', '捌', '玖'
            ];
            var unit = [
                ['元', '万', '亿'],
                ['', '拾', '佰', '仟']
            ];
            var head = n < 0 ? '欠' : '';
            n = Math.abs(n);
            var s = '';
            for (var i = 0; i < fraction.length; i++) {
                s += (digit[Math.floor(n * 10 * Math.pow(10, i)) % 10] + fraction[i]).replace(/零./, '');
            }
            s = s || '整';
            n = Math.floor(n);
            for (var i = 0; i < unit[0].length && n > 0; i++) {
                var p = '';
                for (var j = 0; j < unit[1].length && n > 0; j++) {
                    p = digit[n % 10] + unit[1][j] + p;
                    n = Math.floor(n / 10);
                }
                s = p.replace(/(零.)*零$/, '').replace(/^$/, '零') + unit[0][i] + s;
            }
            return head + s.replace(/(零.)*零元/, '元')
                .replace(/(零.)+/g, '零')
                .replace(/^整$/, '零元整');
        },

        //四舍五入保留2位小数（不够位数，则用0替补）
        keepTwoDecimalFull: function (num) {

            var result = parseFloat(num);

            if (isNaN(result)) {
                console.error('参数非数值，无法四舍五入保留两位小数！');
                return false;
            }

            result = Math.round(num * 100) / 100;

            var s_x = result.toString();
            var pos_decimal = s_x.indexOf('.');
            if (pos_decimal < 0) {
                 pos_decimal = s_x.length;
                 s_x += '.';
            }
            while (s_x.length <= pos_decimal + 2) {
                s_x += '0';
            }
            return s_x;
        },

        //四舍五入保留2位小数（不够位数，则用0替补）
        keepOneDecimalFull: function (num) {

            var result = parseFloat(num);

            if (isNaN(result)) {
                console.error('参数非数值，无法四舍五入保留两位小数！');
                return false;
            }

            result = Math.round(num * 10) / 10;

            var s_x = result.toString();
            var pos_decimal = s_x.indexOf('.');
            if (pos_decimal < 0) {
                pos_decimal = s_x.length;
                s_x += '.';
            }
            while (s_x.length <= pos_decimal + 1) {
                s_x += '0';
            }
            return s_x;
        },


        /*
        * @authors 川川 (itclancode@163.com)
        * @ID suibichuanji
        * @weChatNum 微信公众号:itclancoder
        * @version $Id$
        * @desc 数字格式化处理
        */
        // num接收的数字, point保留数字的第几位
        tranNumber: function(num, point){
            // 将数字转换为字符串,然后通过split方法用.分隔,取到第0个
            let numStr = num.toString().split('.')[0]
            if(numStr.length<6) { // 判断数字有多长,如果小于6,,表示10万以内的数字,让其直接显示
                console.log(numStr);
                return numStr;
            }else if(numStr.length>=6 && numStr.length<=8){ // 如果数字大于6位,小于8位,让其数字后面加单位万
                let decimal = numStr.substring(numStr.length-4, numStr.length-4+point)
                console.log(decimal);
                // 由千位,百位组成的一个数字
                return parseFloat(parseInt(num / 10000)+'.'+decimal)+'万'
            }else if(numStr.length >8){ // 如果数字大于8位,让其数字后面加单位亿
                let decimal = numStr.substring(numStr.length-8, numStr.length-8+point);
                console.log(decimal);
                return parseFloat(parseInt(num/100000000)+'.'+decimal)+'亿'
            }
        },

        toThousandsNum: function (num) {

            if(num)
            {
                //将num中的$,去掉，将num变成一个纯粹的数据格式字符串
                num = num.toString().replace(/\$|\,/g,'');
                //如果num不是数字，则将num置0，并返回
                if(''==num || isNaN(num)){return 'Not a Number ! ';}
                //如果num是负数，则获取她的符号
                var sign = num.indexOf("-")> 0 ? '-' : '';
                //如果存在小数点，则获取数字的小数部分
                var cents = num.indexOf(".")> 0 ? num.substr(num.indexOf(".")) : '';
                cents = cents.length>1 ? cents : '' ;//注意：这里如果是使用change方法不断的调用，小数是输入不了的
                //获取数字的整数数部分
                num = num.indexOf(".")>0 ? num.substring(0,(num.indexOf("."))) : num ;
                //如果没有小数点，整数部分不能以0开头
                if('' == cents){ if(num.length>1 && '0' == num.substr(0,1)){return 'Not a Number ! ';}}
                //如果有小数点，且整数的部分的长度大于1，则整数部分不能以0开头
                else{if(num.length>1 && '0' == num.substr(0,1)){return 'Not a Number ! ';}}
                //针对整数部分进行格式化处理，这是此方法的核心，也是稍难理解的一个地方，逆向的来思考或者采用简单的事例来实现就容易多了
                /*
                  也可以这样想象，现在有一串数字字符串在你面前，如果让你给他家千分位的逗号的话，你是怎么来思考和操作的?
                  字符串长度为0/1/2/3时都不用添加
                  字符串长度大于3的时候，从右往左数，有三位字符就加一个逗号，然后继续往前数，直到不到往前数少于三位字符为止
                 */
                for (var i = 0; i < Math.floor((num.length-(1+i))/3); i++)
                {
                    num = num.substring(0,num.length-(4*i+3))+','+num.substring(num.length-(4*i+3));
                }
                //将数据（符号、整数部分、小数部分）整体组合返回
                return (sign + num + cents);
            }

            return num;

        },

        quickPrint: function(options){

            if(options.url.indexOf("?") >= 0){
                options.url = options.url + '&token=' + SessionUtils.getToken();
            }else{
                options.url = options.url + '?token=' + SessionUtils.getToken();
            }

            $("#printIframe").remove();
            $("body").append("<iframe style='display:none' id='printIframe' src='" + options.url + "'></iframe>");
            $("#printIframe").load(function(){
                $("#printIframe")[0].contentWindow.print();
            });

            /*if(options.onafterprint){

                var mediaQueryList = window.matchMedia('print');
                mediaQueryList.addListener(function(mql) {
                    if (mql.matches) {
                        console.info("取消打印");
                    } else {
                        console.info("已打印2");
                        options.onafterprint();
                    }

                    mediaQueryList.removeEventListener(function (){});
                });
            }*/

        },

        domPrint: function(options){


        },

        print: function(filePath){

            var index = Win.open({
                content: filePath,
                width: '70%',
                height: '95%',
                type: 2,
                offset: 't',
                anim: 0,
                skin: '-1',
                isOutAnim: false
            })

        },

        multiPrint: function (files) {

            FdpCommand.register({
                module: "PUBLIC-PRINT",
                cmdName: "multiPrintParam",
                callBack: function (options) {
                    return files;
                }
            })

            var index = Win.open({
                content: GLOBAL.path.adminApi + "/view/lib/multiPrint",
                width: '70%',
                height: '95%',
                type: 2,
                offset: 't',
                anim: 0,
                skin: '-1',
                isOutAnim: false
            })

            top.layui.$("#layui-layer" + index).css({"background" : "none", "box-shadow" : "none"})
        },

        canvasDataURL: function(file, callback) { //压缩转化为base64
            var reader = new FileReader()
            reader.readAsDataURL(file)
            reader.onload = function (e) {
                const img = new Image()
                const quality = 0.5 // 图像质量
                const canvas = document.createElement('canvas')
                const drawer = canvas.getContext('2d')
                img.src = this.result
                img.onload = function () {
                    canvas.width = img.width
                    canvas.height = img.height
                    drawer.drawImage(img, 0, 0, canvas.width, canvas.height)
                    Utils.convertBase64UrlToBlob(canvas.toDataURL(file.type, quality), callback);
                }
            }
        },

        convertBase64UrlToBlob: function (urlData, callback) { //将base64转化为文件格式
            const arr = urlData.split(',')
            const mime = arr[0].match(/:(.*?);/)[1]
            const bstr = atob(arr[1])
            let n = bstr.length
            const u8arr = new Uint8Array(n)
            while (n--) {
                u8arr[n] = bstr.charCodeAt(n)
            }
            callback(new Blob([u8arr], {
                type: mime
            }));
        }
    }

    window.DataConvert = {
        /**
         * 将普通列表无限递归转换为树
         * @param  {[type]} list       [普通的列表，必须包括 opt.primaryKey 指定的键和 opt.parentKey 指定的键]
         * @param {[type]} opt [配置参数，支持 primaryKey(主键 默认id) parentKey(父级id对应键 默认pid) nameKey(节点标题对应的key 默认name) valueKey(节点值对应的key 默认id) checkedKey、disabledKey(节点是否选中的字段 默认checked，传入数组则判断主键是否在此数组中) startPid(第一层扫描的PID 默认0) currentDept(当前层 默认0) maxDept(最大递归层 默认100) childKey(递归完成后子节点对应键 默认list) deptPrefix(根据层级重复的前缀 默认'')]
         * @return {[type]}            [description]
         */
        listToTreeConvert: function(list, opt) {
            opt = opt || {};
            opt.primaryKey = opt.primaryKey ? opt.primaryKey : 'code';
            opt.parentKey = opt.parentKey ? opt.parentKey : 'parentCode';
            opt.startPid = opt.startPid ? opt.startPid : '';
            opt.currentDept = opt.currentDept ? parseInt(opt.currentDept) : 0;
            opt.maxDept = opt.maxDept ? opt.maxDept : 100;
            opt.childKey = opt.childKey ? opt.childKey : 'children';
            opt.checkedKey = opt.checkedKey ? opt.checkedKey : 'checked';
            opt.disabledKey = opt.disabledKey ? opt.disabledKey : 'disabled';
            opt.nameKey = opt.nameKey ? opt.nameKey : 'label';
            opt.valueKey = opt.valueKey ? opt.valueKey : 'code';
            opt.labelKey = opt.labelKey ? opt.labelKey : 'label';
            return this._listToTree(list, opt.startPid, opt.currentDept, opt);
        },
        // 实际的递归函数，将会变化的参数抽取出来
        _listToTree: function(list, startPid, currentDept, opt) {
            if (opt.maxDept < currentDept) {
                return [];
            }
            var child = [];
            for (var index in list) {
                if (list.hasOwnProperty(index)) {
                    // 筛查符合条件的数据（主键 = startPid）
                    var item = list[index];
                    if (typeof item[opt.parentKey] !== 'undefined' && item[opt.parentKey] === startPid) {
                        // 满足条件则递归
                        var nextChild = this._listToTree(list, item[opt.primaryKey], currentDept+1, opt);
                        // 节点信息保存
                        var node = {};
                        if (nextChild.length > 0) {
                            node[opt.childKey] = nextChild;
                        }
                        node[opt.labelKey] = item[opt.nameKey];
                        node['value'] = item[opt.valueKey];
                        node['data'] = item;
                        // 禁用/选中节点的两种渲染方式
                        node['checked'] = this._getStatusByDynamicKey(item, opt.checkedKey, opt.valueKey);
                        node['disabled'] = this._getStatusByDynamicKey(item, opt.disabledKey, opt.valueKey);
                        child.push(node);
                    }
                }
            }
            return child;
        },
        // 通过动态key，获取状态信息，dynamicKey支持：数字/字符时直接取属性，对象时查看是否在数组中
        _getStatusByDynamicKey: function(item, dynamicKey, valueKey) {
            var isChecked = false;
            if (typeof dynamicKey === "string" || typeof dynamicKey === 'number') {
                isChecked = item[dynamicKey];
            } else if(typeof dynamicKey === 'object') {
                isChecked = $.inArray(item[valueKey], dynamicKey) !== -1;
            } else {
                isChecked = false;
            }
            return isChecked;
        },

        treeToListConvert: function(treeObj, options) {

            var that = this;

            options = options || {};

            options.childKey = options.childKey || "children";
            options.rootid = options.rootid || "";

            const temp = [];  // 设置临时数组，用来存放队列
            const out = [];    // 设置输出数组，用来存放要输出的一维数组
            temp.push(treeObj);
            // 首先把根元素存放入out中
            let pid = options.rootid;
            const obj = that._deepCopy(treeObj);
            obj.pid = pid;
            delete obj[options.childKey];
            out.push(obj)
            // 对树对象进行广度优先的遍历
            while(temp.length > 0) {
                const first = temp.shift();
                const children = first.children;
                if(children && children.length > 0) {
                    pid = first.id;
                    const len = first.children.length;
                    for(let i=0;i<len;i++) {
                        temp.push(children[i]);
                        const obj = that._deepCopy(children[i]);
                        obj.pid = pid;
                        delete obj[options.childKey];
                        out.push(obj)
                    }
                }
            }
            return out
        },

        _deepCopy: function (obj){

            var that = this;

            // 深度复制数组
            if(Object.prototype.toString.call(obj) === "[object Array]"){
                const object=[];
                for(let i=0;i<obj.length;i++){
                    object.push(that._deepCopy(obj[i]))
                }
                return object
            }
            // 深度复制对象
            if(Object.prototype.toString.call(obj) === "[object Object]"){
                const object={};
                for(let p in obj){
                    object[p]=obj[p]
                }
                return object
            }
        }

    }

    window.FdpCommand = {

        _Command: new Map(),

        /**
         * 注册命令
         * {
         *     module: "sys-dict" //模块标识
         *     cmdName: "updateTree" //命令名称
         *     callBack: function(options)  //命令具体实现
         * }
         * @param options
         */
        register: function (options) {

            if(!options || !options.module || !options.cmdName || !options.callBack){
                console.error("FdpCommand register 参数异常【options】：" + JSON.stringify(options));
                return;
            }

            if(!top.FdpCommand._Command.get(options.module)){
                top.FdpCommand._Command.set(options.module, new Map());
            }

            top.FdpCommand._Command.get(options.module).set(options.cmdName, options.callBack);
        },

        /**
         * 执行命令
         * {
         *     module: "sys-dict" //模块标识
         *     cmdName: "updateTree" //命令名称
         *     options: null //命令具体实现参数
         * }
         * @param options
         */
        execute: function (options) {

            if(!options || !options.module || !options.cmdName){
                console.error("FdpCommand execute 参数异常【options】：" + JSON.stringify(options));
                return;
            }

            if(!top.FdpCommand._Command.get(options.module) || !top.FdpCommand._Command.get(options.module).get(options.cmdName)){
                console.error("FdpCommand execute 命令未注册：" + JSON.stringify(options));
                return;
            }

            return top.FdpCommand._Command.get(options.module).get(options.cmdName)(options.options);
        }
    }

    window.UUID = function(){
        var d = new Date().getTime();
        var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
            var r = (d + Math.random()*16)%16 | 0;
            d = Math.floor(d/16);
            return (c=='x' ? r : (r&0x3|0x8)).toString(16);
        });
        return uuid;
    }


    window.CommonFun = {

        add: function(options) {

            http.post({
                url: GLOBAL.path.adminApi + '/sys/commonFun/add',
                async: false,
                data: options,
                hideLoading: true,
                backFun: function(result){

                }});
        },

        list: function(options){

            var result = [];

            http.post({
                url: GLOBAL.path.adminApi + '/sys/commonFun/list',
                async: false,
                data: options,
                backFun: function(data){
                    result = data;
                }});

            return result;
        }
    }

    /**
     * 富文本编辑器
     * @type {{}}
     */
    window.Editor = {

        init: function (params) {

            var that = this;

            that.loadPlugin(function () {

                var container = params.container;
                if("undefined" == typeof params.refreshWidth){
                    params.refreshWidth = true;
                }
                if("undefined" == typeof params.showMenus){
                    params.showMenus = true;
                }
                if("undefined" == typeof params.showFullScreen){
                    params.showFullScreen = true;
                }

                var E = window.wangEditor;

                var editor = null;
                if(container.length > 1){
                    editor = new E(container[0], container[1]);
                }else{
                    editor = new E(container[0]);
                }

                if(!params.contenteditable){
                    editor.config.menus = ['fullscreen'];
                }

                editor.config.showFullScreen = params.showFullScreen;

                if(params.height){
                    editor.config.height = params.height;
                }

                if(params.syncTextArea){
                    editor.config.onchange = function (newHtml) {
                        // 监控变化，同步更新到 textarea
                        params.syncTextArea.val(newHtml);
                    }

                    // 配置触发 onchange 的时间频率，默认为 200ms
                    editor.config.onchangeTimeout = 500 // 修改为 500ms
                }

                if(params.imgMenuClickEvent){
                    editor.txt.eventHooks.imgMenuClickEvent = params.imgMenuClickEvent;
                }

                if(params.videoMenuClickEvent){
                    editor.txt.eventHooks.videoMenuClickEvent = params.videoMenuClickEvent;
                }

                editor.config.uploadImgServer =  GLOBAL.path.adminApi + Appendix.getUploadUrl();

                editor.create();

                if(params.contenteditable){
                    editor.enable();
                }else{
                    editor.disable();
                    //editor.disableMenusExcept = ['fullscreen'];
                    //container.parent().find(".menu-group").css("float", "right");
                }

                if(params.content){
                    editor.txt.html(params.content);
                }

                if(params.fullScreen){
                    editor.fullScreen(); // 全屏
                    editor.config.showFullScreen = false;//隐藏全屏按钮
                }

                return editor;
            })
        },

        loadPlugin: function (backFun) {

            if(!window.wangEditor){
                http.getScript( GLOBAL.path.adminApi + "/static/lib/wangEditor-v4.6/dist/wangEditor.js" , function(){
                    backFun();
                })
            }else{
                backFun();
            }
        }
    }

    /**
     * 导出
     */
    window.Export = {

        execute: function(options) {

            let exportParam = {
                busType: options.busType,
                params: options.params
            };

            let exportUrl = GLOBAL.path.adminApi + "/public/export";
            var xmlResquest = null;

            if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari
                xmlResquest = new XMLHttpRequest();
            } else {// code for IE6, IE5
                xmlResquest = new ActiveXObject("Microsoft.XMLHTTP");
            }
            xmlResquest.open(options.reqType ? options.reqType : "post", exportUrl, true);
            xmlResquest.setRequestHeader("token", LocalStorageUtils.get(GLOBAL.cacheKeys.ACCESS_TOKEN));
            xmlResquest.setRequestHeader("Content-Type", "application/json");
            xmlResquest.responseType = "blob";
            xmlResquest.onload = function (oEvent) {
                var content = xmlResquest.response;
                var elink = document.createElement('a');
                var fileName = '';
                if (options.fileName) {
                    fileName = options.fileName;
                } else {
                    var contentDisposition = xmlResquest.getResponseHeader('Content-Disposition');
                    var filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
                    var matches = filenameRegex.exec(contentDisposition);
                    if (matches != null && matches[1]) {
                        fileName = decodeURI(matches[1].replace(/['"]/g, ''));
                    }
                }
                elink.download = fileName;

                elink.style.display = 'none';
                var blob = new Blob([content]);
                elink.href = URL.createObjectURL(blob);
                document.body.appendChild(elink);
                elink.click();
                document.body.removeChild(elink);
            };

            xmlResquest.send(JSON.stringify(exportParam));
        }
    }

    exports("FdpUtil", {
        SessionUtils: SessionUtils,
        Dict: Dict,
        Identity: Identity,
        Win: Win,
        QueryParam: QueryParam,
        DataVerify: DataVerify,
        Appendix: Appendix,
        DateUtil: DateUtil,
        FileType: FileType,
        LocalStorageUtils: LocalStorageUtils,
        HanyuPinyinHelper: HanyuPinyinHelper,
        FdpCommand: FdpCommand,
        UUID: UUID,
        Utils: Utils,
        CommonFun: CommonFun,
        Editor: Editor,
        Export: Export
    })

})
